/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       material_pile.cpp

	$Header: /game/material_pile.cpp $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "material_pile.h"

#include "adv_object_model.h"
#include "adventure_frame.h"
#include "adventure_map.h"
#include "adventure_map_window.h"
#include "adventure_sounds.h"
#include "adv_object_strings.h"
#include "army.h"
#include "material_names.h"
#include "mouse_event.h"
#include "object_registration.h"
#include "player.h"
#include "random.h"
#include "replace_keywords.h"
#include "simple_dialog.h"
#include "sized_int_types.h"
#include "standard_fonts.h"
#include "streambuf_operators.h"
#include "text_window.h"
#include "timed_window.h"

// ---------------------------------------------------------------
// Unnamed namespace
// ---------------------------------------------------------------

namespace
{

	// ---------------------------------------------------------------
	// ---------------------------------------------------------------
	int const k_current_map_format_version = 0;

	// ---------------------------------------------------------------
	// ---------------------------------------------------------------
	int pick_material_amount( t_material material )
	{
		assert( material >= 0 && material < k_material_count );

		int result;
		switch ( material )
		{
			case k_gold:
				result = random( 4, 8 ) * 100;
				break;

			case k_wood:
			case k_ore:
				result = random( 4, 8 );
				break;

			case k_crystal:
			case k_sulfur:
			case k_mercury:
			case k_gems:
				result = random( 2, 4 );
				break;

			default:
				assert( false );
		}

		return result;
	}

} // Unnamed namespace

static t_object_registration<t_material_pile> k_pile_registration( k_adv_object_material_pile );
static t_object_registration<t_random_material_pile> 
       k_random_registration( k_adv_object_random_material_pile );

static char const* k_model_name[k_material_count] =
{
	"resources.gold",
	"resources.wood",
	"resources.ore",
	"resources.crystal",
	"resources.sulfur",
	"resources.mercury",
	"resources.gem",
};

t_material_pile::t_material_pile( t_material type )
               : t_stationary_adventure_object( k_model_name[type] )
{
	m_amount.material = type;
	m_amount.amount = pick_material_amount( m_amount.material );
}

// ---------------------------------------------------------------
// a freestanding lump of material
// ---------------------------------------------------------------
t_material_pile::t_material_pile( t_stationary_adventure_object const& source )
               : t_stationary_adventure_object( source )
{
	t_adv_object_model const& model = get_model();
	
	m_amount.material = t_material( get_major_subtype() );
	m_amount.amount = pick_material_amount( m_amount.material );
}

// ---------------------------------------------------------------
// a freestanding lump of material
// ---------------------------------------------------------------
void t_material_pile::activate_trigger( t_army* army, t_adv_map_point const& point, 
		                                t_direction direction, t_adventure_frame* frame )
{
	t_player* owner = army->get_owner();

	owner->gain( m_amount.material, m_amount.amount );
	if (!army->get_owner()->is_computer())
	{
		t_adventure_map*		 map = frame->get_map();
		t_adventure_map_window*  map_window = frame->get_map_window();
		t_screen_point           screen_point;
		t_window*				 timed_window;
		t_text_window*			 text_window;
		std::string              text;

		screen_point = get_screen_point( *map, *this, get_position() ) - map_window->get_view_pos();
		timed_window = new t_timed_window( screen_point, map_window, 3000, 
			                                         t_screen_point( -1, -1 ), 100 );
		text = format_string( "+%i ", m_amount.amount ) 
				+ get_material_name( m_amount.material );
		text_window = new t_text_window( get_font( 25 ), t_screen_point(0,0), 
			                             timed_window, text, t_pixel_24( 255, 255, 255 ) );
		text_window->set_drop_shadow( true );
		frame->update_funds();

		t_adventure_sound_type type = (t_adventure_sound_type)( (int)k_adventure_sound_pickup_1 + random(0,5) );
		get_adventure_sound( type )->play( get_sound_volume() );
	}
	destroy();
}

void t_material_pile::right_click( t_mouse_event const& event,
		                                         t_adventure_frame* adventure_frame )
{
	std::string    help_text = get_string( get_type(), "help" );

	if (help_text.empty())
		return;

	help_text = replace_keywords( help_text, "%material_name", get_name() );
	show_popup_text( help_text, event.screen_point );
}

// ---------------------------------------------------------------
// a freestanding lump of material
// ---------------------------------------------------------------
float t_material_pile::ai_value( t_adventure_ai const& ai, t_creature_array const& army, int move_cost ) const
{
	t_player* player = army.get_owner();
	float adjusted_value = player->get_material_value(m_amount.material) * m_amount.amount;
	return adjusted_value;
}

// ---------------------------------------------------------------
// a freestanding lump of material
// ---------------------------------------------------------------
bool t_material_pile::write( std::streambuf& stream ) const
{
	::write( stream, &m_amount, sizeof(m_amount ));
	return true;
}

// ---------------------------------------------------------------
// a freestanding lump of material
// ---------------------------------------------------------------
bool t_material_pile::read( std::streambuf&						stream, 
						   t_qualified_adv_object_type const&	type,
						   int									version ) 
{
	::read( stream, &m_amount, sizeof(m_amount));
	return true;
}

// ---------------------------------------------------------------
// a random freestanding lump of material
// ---------------------------------------------------------------
t_random_material_pile::t_random_material_pile( std::string const& source )
					  : t_stationary_adventure_object( source )
{
}

// ---------------------------------------------------------------
// a random freestanding lump of material
// ---------------------------------------------------------------
void t_random_material_pile::place( t_adventure_map& map, t_adv_map_point const& point )
{
	t_material		 type = random( k_material_count );
	t_material_pile* pile = new t_material_pile( type );

	pile->place( map, point );
}

